package com.papers.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.papers.common.constant.CacheNames;
import com.papers.common.core.domain.PageQuery;
import com.papers.common.core.domain.R;
import com.papers.common.core.domain.dto.RoleDTO;
import com.papers.common.core.domain.entity.SysDept;
import com.papers.common.core.domain.entity.SysDictData;
import com.papers.common.core.domain.entity.SysUser;
import com.papers.common.core.page.TableDataInfo;
import com.papers.common.exception.ServiceException;
import com.papers.common.helper.LoginHelper;
import com.papers.common.utils.DateUtils;
import com.papers.common.utils.StringUtils;
import com.papers.common.utils.redis.CacheUtils;
import com.papers.juan.domain.TJuanQuestion;
import com.papers.juan.mapper.TJuanQuestionMapper;
import com.papers.system.domain.TJuanChapter;
import com.papers.system.domain.TJuanCourse;
import com.papers.system.domain.TJuanKnowledge;
import com.papers.system.domain.TJuanMajor;
import com.papers.system.domain.TJuanUserCourse;
import com.papers.system.domain.bo.TJuanCourseBo;
import com.papers.system.domain.dto.TJuanCourseDto;
import com.papers.system.domain.dto.TJuanUserCourseDto;
import com.papers.system.domain.vo.TJuanChapterOutVo;
import com.papers.system.domain.vo.TJuanCourseListVo;
import com.papers.system.domain.vo.TJuanCourseVo;
import com.papers.system.domain.vo.TJuanLeftTreeListVo;
import com.papers.system.domain.vo.TJuanMajorTreeVo;
import com.papers.system.domain.vo.TJuanTkChildVO;
import com.papers.system.domain.vo.TJuanTkTotal;
import com.papers.system.domain.vo.TJuanTkVO;
import com.papers.system.mapper.SysDeptMapper;
import com.papers.system.mapper.TJuanChapterMapper;
import com.papers.system.mapper.TJuanCourseMapper;
import com.papers.system.mapper.TJuanDepartmentMapper;
import com.papers.system.mapper.TJuanKnowledgeMapper;
import com.papers.system.mapper.TJuanMajorMapper;
import com.papers.system.mapper.TJuanUserCourseMapper;
import com.papers.system.service.ISysDeptService;
import com.papers.system.service.ITJuanChapterService;
import com.papers.system.service.ITJuanCourseService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 课程Service业务层处理
 *
 * @author papers
 * @date 2022-10-12
 */
@RequiredArgsConstructor
@Service
public class TJuanCourseServiceImpl implements ITJuanCourseService {

    private final TJuanCourseMapper baseMapper;
    private final TJuanDepartmentMapper departmentMapper;
    private final TJuanMajorMapper majorMapper;
    private final TJuanChapterMapper tJuanChapterMapper;
    private final TJuanUserCourseMapper userCourseMapper;
    private final SysDeptMapper sysDeptMapper;
    private final ISysDeptService sysDeptService;
    private final ITJuanChapterService itJuanChapterService;
    private final TJuanKnowledgeMapper juanKnowledgeMapper;

    private final TJuanQuestionMapper questionMapper;

    /**
     * 查询课程
     */
    @Override
    public TJuanCourseVo queryById(String courseId) {
        return baseMapper.getVoById(courseId);
    }

    /**
     * 查询课程列表
     */
    @Override
    public TableDataInfo<TJuanCourseVo> queryPageList(TJuanCourseDto dto, PageQuery pageQuery) {
        //查询本部门的可见权限，查出本部门以及所有子部门
        Long deptId = LoginHelper.getDeptId();
        //查看本人的角色
        List<RoleDTO> roles = LoginHelper.getRoles();
        //如果角色有且只有一个教员，则他只能看到他自己创建的题库
        if (roles.size() == 1) {
            if ("教员".equals(roles.get(0).getRoleName())) {
                dto.setUserName(LoginHelper.getUsername());
            }
        }
        SysDept sysDept = sysDeptMapper.selectVoById(deptId);
        List<SysDept> depts = sysDeptMapper.selectList(new LambdaQueryWrapper<SysDept>()
            .eq(SysDept::getDeptId, deptId).or().like(SysDept::getAncestors, sysDept.getAncestors() + "," + sysDept.getDeptId()));
        List<SysDept> deptList = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getDepartment())) {
            SysDept sysDeptLike = sysDeptMapper.selectVoById(Long.parseLong(dto.getDepartment()));
            deptList = sysDeptMapper.selectList(new LambdaQueryWrapper<SysDept>()
                .eq(SysDept::getDeptId, sysDeptLike.getDeptId()).or().like(SysDept::getAncestors, sysDeptLike.getAncestors() + "," + sysDeptLike.getDeptId()));
        }
        Page<TJuanCourseVo> page = baseMapper.getCourseByPage(pageQuery.build(), dto, depts, deptList);
        for (TJuanCourseVo item : page.getRecords()) {
            List<String> majorNameList = majorMapper.getMajorName(item.getMajorId());
            List<String> deptNameList = departmentMapper.getDeptName(item.getDepartId());
            String newName1 = majorNameList.stream().collect(Collectors.joining(","));
            String newName2 = deptNameList.stream().collect(Collectors.joining(","));
//            String newName1 = majorNameList.get(0);
//            majorNameList.remove(0);
//            String newName2 = deptNameList.get(0);
//            deptNameList.remove(0);
//            if (null != majorNameList || 0 != majorNameList.size()) {
//                for (String oldName : majorNameList) {
//                    newName1 += "," + oldName;
//                }
//            }
//            if (null != deptNameList || 0 != deptNameList.size()) {
//                for (String oldName : deptNameList) {
//                    newName2 += "," + oldName;
//                }
//            }
            item.setMajorName(newName1);
            item.setDepartName(newName2);
        }
        return TableDataInfo.build(page);
    }

    /**
     * 查询课程列表
     */
    @Override
    public List<TJuanCourseListVo> queryList(TJuanCourseBo bo) {
        if (ObjectUtils.isNull(bo.getDepartment())) {
            throw new ServiceException("请先选择组织机构");
        }
        List<TJuanCourseListVo> courseList = baseMapper.getCourseList(bo);
        LambdaQueryWrapper<SysDept> lqw1 = new LambdaQueryWrapper<>();
        lqw1.eq(SysDept::getParentId, "0");
        SysDept dept1 = sysDeptMapper.selectOne(lqw1);
        for (TJuanCourseListVo item : courseList) {
            item.setDepart1(dept1.getDeptName());
            LambdaQueryWrapper<SysDept> lqw2 = new LambdaQueryWrapper<>();
            lqw2.eq(SysDept::getDeptCode, item.getCourseCode().substring(0, 1));
            SysDept dept2 = sysDeptMapper.selectOne(lqw2);
            if (item.getCourseCode().length() == 3) {
                item.setDepart2(dept2.getDeptName());
            } else if (item.getCourseCode().length() == 4) {
                LambdaQueryWrapper<SysDept> lqw3 = new LambdaQueryWrapper<>();
                lqw3.eq(SysDept::getDeptCode, item.getCourseCode().substring(0, 2));
                SysDept dept3 = sysDeptMapper.selectOne(lqw3);
                item.setDepart2(dept2.getDeptName());
                item.setDepart3(dept3.getDeptName());
            }
        }
        return courseList;
    }

    private LambdaQueryWrapper<TJuanCourse> buildQueryWrapper(TJuanCourseBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TJuanCourse> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getMajorId()), TJuanCourse::getMajorId, bo.getMajorId());
        lqw.eq(StringUtils.isNotBlank(bo.getDepartId()), TJuanCourse::getDepartId, bo.getDepartId());
        lqw.eq(StringUtils.isNotBlank(bo.getCourseCode()), TJuanCourse::getCourseCode, bo.getCourseCode());
        lqw.eq(StringUtils.isNotBlank(bo.getCourseSubject()), TJuanCourse::getCourseSubject, bo.getCourseSubject());
        lqw.eq(StringUtils.isNotBlank(bo.getCourseType()), TJuanCourse::getCourseType, bo.getCourseType());
        lqw.eq(StringUtils.isNotBlank(bo.getCourseConstruction()), TJuanCourse::getCourseConstruction, bo.getCourseConstruction());
        lqw.eq(StringUtils.isNotBlank(bo.getCourseCount()), TJuanCourse::getCourseCount, bo.getCourseCount());
        lqw.eq(bo.getCourseHierarchy() != null, TJuanCourse::getCourseHierarchy, bo.getCourseHierarchy());
        lqw.eq(StringUtils.isNotBlank(bo.getCourseDes()), TJuanCourse::getCourseDes, bo.getCourseDes());
        lqw.eq(StringUtils.isNotBlank(bo.getCreatedBy()), TJuanCourse::getCreatedBy, bo.getCreatedBy());
        lqw.eq(bo.getCreatedTime() != null, TJuanCourse::getCreatedTime, bo.getCreatedTime());
        lqw.eq(StringUtils.isNotBlank(bo.getUpdatedBy()), TJuanCourse::getUpdatedBy, bo.getUpdatedBy());
        lqw.eq(bo.getUpdatedTime() != null, TJuanCourse::getUpdatedTime, bo.getUpdatedTime());
        return lqw;
    }

    /**
     * 新增课程
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(TJuanCourseBo bo) {
        TJuanCourse add = BeanUtil.toBean(bo, TJuanCourse.class);
        LambdaQueryWrapper<SysDept> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysDept::getDeptId, bo.getDepartment());
        SysDept sysDept = sysDeptMapper.selectOne(lambdaQueryWrapper);
        if (sysDept.getParentId() == 0) {
            throw new ServiceException("请选择部系或教研室");
        }
        add.setUpdatedBy(LoginHelper.getUsername());
        add.setCreatedBy(LoginHelper.getUsername());
        add.setCreatedTime(DateUtils.getNowDate());
        add.setUpdatedTime(DateUtils.getNowDate());

        LambdaQueryWrapper<TJuanCourse> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TJuanCourse::getDepartment, bo.getDepartment())
            .orderByDesc(TJuanCourse::getCourseCode)
            .last("LIMIT 1");
        TJuanCourse course = baseMapper.selectOne(queryWrapper);

        String newCode;
        if (ObjectUtils.isNull(course)) {
            newCode = sysDept.getDeptCode() + "01";
//            newCode = "01";
        } else {
            List<String> courses = baseMapper.selectCodeList(bo.getDepartment());
            int oldCode = Integer.parseInt(course.getCourseCode().substring(course.getCourseCode().length() - 2));
            if (oldCode != courses.size()) {
                int currentCode = 01;
                for (String item : courses) {
                    if (currentCode != Integer.parseInt(item.substring(course.getCourseCode().length() - 2))) {
                        oldCode = currentCode - 1;
                        break;
                    }
                    currentCode++;
                }
            }
            oldCode++;
            if (oldCode > 99) {
                throw new ServiceException("已达到题库最大数量，请联系管理员");
            }
            newCode = sysDept.getDeptCode().concat(String.format("%02d", oldCode));
        }
        add.setCourseCode(newCode);

        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setCourseId(add.getCourseId());
        }
        return flag;
    }

    /**
     * 查看题库编码
     *
     * @param bo
     * @return
     */
    @Override
    public String checkCourseCode(TJuanCourseBo bo) {
        LambdaQueryWrapper<SysDept> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysDept::getDeptId, bo.getDepartment());
        SysDept sysDept = sysDeptMapper.selectOne(lambdaQueryWrapper);
        if (sysDept.getParentId() == 0) {
            throw new ServiceException("请选择部系或教研室");
        }
        LambdaQueryWrapper<TJuanCourse> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TJuanCourse::getDepartment, bo.getDepartment())
            .orderByDesc(TJuanCourse::getCourseCode)
            .last("LIMIT 1");
        TJuanCourse course = baseMapper.selectOne(queryWrapper);

        String newCode;
        if (ObjectUtils.isNull(course)) {
            newCode = sysDept.getDeptCode() + "01";
        } else {
            List<String> courses = baseMapper.selectCodeList(bo.getDepartment());
            int oldCode = Integer.parseInt(course.getCourseCode().substring(course.getCourseCode().length() - 2));
            if (oldCode != courses.size()) {
                int currentCode = 01;
                for (String item : courses) {
                    if (currentCode != Integer.parseInt(item.substring(course.getCourseCode().length() - 2))) {
                        oldCode = currentCode - 1;
                        break;
                    }
                    currentCode++;
                }
            }
            oldCode++;
            if (oldCode > 99) {
                throw new ServiceException("已达到题库最大数量，请联系管理员");
            }
            newCode = sysDept.getDeptCode().concat(String.format("%02d", oldCode));
        }
        return newCode;
    }

    /**
     * 修改课程
     */
    @Override
    public Boolean updateByBo(TJuanCourseBo bo) {
        TJuanCourse update = BeanUtil.toBean(bo, TJuanCourse.class);

        update.setUpdatedBy(LoginHelper.getUsername());
        update.setUpdatedTime(DateUtils.getNowDate());

        return baseMapper.updateById(update) > 0;
    }

    /**
     * 批量删除课程
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        for (String id : ids) {
            QueryWrapper<TJuanChapter> queryWrapper = new QueryWrapper();
            queryWrapper.lambda().eq(TJuanChapter::getCourseId, id);
            List<TJuanChapter> list = tJuanChapterMapper.selectList(queryWrapper);
            if (list.size() > 0) {
//                throw new ServiceException("该题库下有章节存在，删除失败");
                //章节直接删除
                List<String> chapters = new ArrayList<>();
                for (TJuanChapter tJuanChapter : list) {
                    chapters.add(tJuanChapter.getChapterId());
                }
                String[] ans = chapters.toArray(new String[chapters.size()]);
                itJuanChapterService.deleteByIds(ans);
            }
//            List<SysUser> userList = baseMapper.selectAllUserList(id);
//            if(userList.size() >0 ){
//                throw new ServiceException("该课程下有用户绑定，删除失败");
//            }
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 保存前的数据校验
     */
    @Override
    public int CourseCodeUnique(TJuanCourseBo bo) {
        String courseCode = bo.getCourseCode();
        QueryWrapper<TJuanCourse> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(TJuanCourse::getCourseCode, courseCode);
        queryWrapper.last("LIMIT 1");
        TJuanCourseVo tJuanCourseVo = baseMapper.selectVoOne(queryWrapper);
        /*如存在相同code的对象，返回0*/
        if (tJuanCourseVo == null) {
            return 1;
        } else if (tJuanCourseVo.getCourseId().equals(bo.getCourseId())) {
            return 1;
        } else {
            return 0;
        }
    }

    /**
     * 查询课程
     *
     * @return
     */
    @Override
    public TJuanCourse getOne(String courseId) {
        LambdaQueryWrapper<TJuanCourse> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(null != courseId, TJuanCourse::getCourseId, courseId);
        return baseMapper.selectOne(queryWrapper);
    }

    @Override
    public R getCourseByMajorId() {
        //获取当前用户
        Long userId = LoginHelper.getUserId();
        if (null != userId) {
            List<TJuanCourse> data = baseMapper.getCourseByUserId(userId);
            return R.ok(data);
        }
        return R.fail("系统异常，请联系管理员!");
    }

    /**
     * 导入 课程
     *
     * @param list
     */
    @Override
    public void save(List<TJuanCourseListVo> list) {
//        List<TJuanCourseListVo> courses = new ArrayList<>();
        String newCode;
        for (TJuanCourseListVo item : list) {
            if (item.getMajorCode().length() == 3) {
                item.setMajorCode("0" + item.getMajorCode());
            }
            //没有code
            if (ObjectUtils.isNull(item.getCourseCode())) {
                LambdaQueryWrapper<TJuanMajor> lqw = new LambdaQueryWrapper<>();
                lqw.eq(TJuanMajor::getMajorCode, item.getMajorCode());
                TJuanMajor major = majorMapper.selectOne(lqw);

                LambdaQueryWrapper<TJuanCourse> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(TJuanCourse::getMajorId, major.getMajorId())
                    .orderByDesc(TJuanCourse::getCourseCode)
                    .last("LIMIT 1");
                TJuanCourse course = baseMapper.selectOne(queryWrapper);

                if (ObjectUtils.isNull(course)) {
                    newCode = major.getMajorCode() + "01";
                } else {
                    List<String> courses = baseMapper.selectCodeList(major.getMajorId());
                    int oldCode = Integer.parseInt(course.getCourseCode().substring(course.getCourseCode().length() - 2));
                    if (oldCode != courses.size()) {
                        int currentCode = 01;
                        for (String code : courses) {
                            if (currentCode != Integer.parseInt(code.substring(course.getCourseCode().length() - 2))) {
                                oldCode = currentCode - 1;
                                break;
                            }
                            currentCode++;
                        }
                    }
                    oldCode++;
                    if (oldCode > 99) {
                        throw new ServiceException("已达到课程最大数量，请联系管理员");
                    }
                    newCode = String.format("%02d", oldCode);
                }
                item.setCourseCode(newCode);
                item.setMajorId(major.getMajorId());
                item.setCreatedBy(LoginHelper.getUsername());
                item.setCreatedTime(DateUtils.getNowDate());
            }
            //有code
            else {
                //判断长度，五位在前面补0
                if (item.getCourseCode().length() == 5) {
                    item.setCourseCode("0".concat(item.getCourseCode()));
                }
                //根据majorCode查询 专业
                LambdaQueryWrapper<TJuanCourse> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(TJuanCourse::getCourseCode, item.getCourseCode());
                TJuanCourse course = baseMapper.selectOne(queryWrapper);
                //重复,更新信息
                if (codeVerify(item)) {
                    item.setDepartId(course.getDepartId());
                    item.setMajorId(course.getMajorId());
                    item.setCourseId(course.getCourseId());
                }
                //没有重复，新增
                else {
                    item.setMajorId(course.getMajorId());
                    item.setDepartId(course.getDepartId());
                    item.setCreatedBy(LoginHelper.getUsername());
                    item.setCreatedTime(DateUtils.getNowDate());
                }
            }
            item.setUpdatedBy(LoginHelper.getUsername());
            item.setUpdatedTime(DateUtils.getNowDate());
            TJuanCourse tJuanCourse = BeanUtil.copyProperties(item, TJuanCourse.class);
            baseMapper.insertOrUpdate(tJuanCourse);
        }

    }

    /**
     * 查询专业树
     *
     * @return
     */
    @Override
    public List<TJuanMajorTreeVo> getMajorTreeList() {
        //查 院系
        List<TJuanMajorTreeVo> departTreeList = departmentMapper.getDepartTree();
        List<String> collect = departTreeList.stream().map(item -> {
            item.setParentId("0");
            String id = item.getId();
            return id;
        }).collect(Collectors.toList());

        //查 专业
        if (ObjectUtils.isNull(collect)) {
            return null;
        }
        List<TJuanLeftTreeListVo> majorTreeList = majorMapper.getMajorTreeListVo(collect);
        Map<String, List<TJuanLeftTreeListVo>> map = majorTreeList.stream().collect(Collectors.groupingBy(TJuanLeftTreeListVo::getParentId));
        for (TJuanMajorTreeVo vo : departTreeList) {
            vo.setChildren(map.get(vo.getId()));
        }
        return departTreeList;
    }

    /**
     * 根据课程查询已绑定用户
     *
     * @param pageQuery
     * @param
     * @return
     */
    @Override
    public TableDataInfo<SysUser> selectAllocatedList(PageQuery pageQuery, TJuanUserCourseDto dto) {
        Page<SysUser> page = baseMapper.selectAllocatedList(pageQuery.build(), dto);
        return TableDataInfo.build(page);
    }

    /**
     * 根据课程查询未绑定用户
     *
     * @param pageQuery
     * @param
     * @return
     */
    @Override
    public TableDataInfo<SysUser> selectUnallocatedList(PageQuery pageQuery, TJuanUserCourseDto dto) {
        Page<SysUser> page = baseMapper.selectUnallocatedList(pageQuery.build(), dto);
        return TableDataInfo.build(page);
    }

    /**
     * 批量取消绑定用户
     *
     * @param userIds
     * @return
     */
    @Override
    public void deleteBindUsers(String courseId, String[] userIds) {
        String s = StringUtils.join(userIds, ",");
        baseMapper.deleteBindUsers(courseId, s);
    }

    /**
     * 批量选择绑定用户
     *
     * @param courseId
     * @param userIds
     * @return
     */
    @Override
    public int insertBindUsers(String courseId, String[] userIds) {
        int rows = 1;
        List<TJuanUserCourse> list = new ArrayList<>();
        for (String userId : userIds) {
            TJuanUserCourse tJuanUserCourse = new TJuanUserCourse();
            tJuanUserCourse.setUserId(userId);
            tJuanUserCourse.setCourseId(courseId);
            tJuanUserCourse.setCreatedBy(LoginHelper.getUsername());
            tJuanUserCourse.setUpdatedBy(LoginHelper.getUsername());
            tJuanUserCourse.setCreatedTime(DateUtils.getNowDate());
            tJuanUserCourse.setUpdatedTime(DateUtils.getNowDate());
            list.add(tJuanUserCourse);
        }
        List<TJuanUserCourse> sameList = userCourseMapper.getSameData(courseId);
        for (int i = 0; i < list.size(); i++) {
            for (TJuanUserCourse uc : sameList) {
                if (list.get(i).getUserId().equals(uc.getUserId())) {
                    list.remove(i);
                    break;
                }
            }
        }
        if (list.size() > 0 && list != null) {
            rows = userCourseMapper.insertBatch(list) ? list.size() : 0;
        }
        return rows;
    }

    @Override
    public R getTreeAndCourse() {
        Long deptId = LoginHelper.getDeptId();
        //查询本部门
        SysDept sysDept = sysDeptService.selectDeptById(deptId);
        LambdaQueryWrapper<SysDept> lqw = new LambdaQueryWrapper<>();
        lqw.in(SysDept::getDeptId, sysDept.getAncestors().split(",")).or().eq(SysDept::getDeptId, sysDept.getDeptId())
            .or().like(SysDept::getAncestors, sysDept.getAncestors() + "," + sysDept.getDeptId());
        List<SysDept> dataList = sysDeptMapper.selectDeptList(lqw);
        //加一层题库
        List<SysDept> courseList = baseMapper.getTreeAndCourse(dataList);
        dataList.addAll(courseList);
        return R.ok(sysDeptService.buildDeptTreeSelect(dataList));
    }


    /**
     * 验证编码是否唯一
     *
     * @param item
     * @return
     */
    public boolean codeVerify(TJuanCourseListVo item) {
        List<TJuanCourse> courses = baseMapper.selectList();
        for (TJuanCourse course : courses) {
            if (item.getCourseCode() != null && item.getCourseCode().equals(course.getCourseCode())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<TJuanTkTotal> tikuTotal() {

        //查询所有题库
        TJuanCourseDto dto = new TJuanCourseDto();
        dto.setDepartment("100");
        PageQuery pageQuery = new PageQuery();
        pageQuery.setPageNum(1);
        pageQuery.setPageSize(9999);
        List<TJuanCourseVo> rows = this.queryPageList(dto, pageQuery).getRows();

        if (CollectionUtils.isEmpty(rows)) {
            return null;
        }
        //查询当前所属题库下所有题目
        List<String> tkIds = rows.stream().map(TJuanCourseVo::getCourseId).collect(Collectors.toList());
        List<TJuanQuestion> qsList = questionMapper.selectAllQuestionByUser(tkIds);
        Map<String, List<TJuanQuestion>> questionMap = qsList.stream().collect(Collectors.groupingBy(TJuanQuestion::getCourseId));
        //题目类型字典
        List<SysDictData> topicType = CacheUtils.get(CacheNames.SYS_DICT, "topic_type");
        //难易程度字典
        List<SysDictData> difficulty = CacheUtils.get(CacheNames.SYS_DICT, "difficulty");
        //重要性字典
        List<SysDictData> grade = CacheUtils.get(CacheNames.SYS_DICT, "grade");
        //能力层次字典
        List<SysDictData> capabilityLevel = CacheUtils.get(CacheNames.SYS_DICT, "capability_level");
        // 最终返回结果
        List<TJuanTkTotal> result = new ArrayList<>();
        for (TJuanCourseVo item : rows) {
            TJuanTkTotal tk = new TJuanTkTotal();
            tk.setTkId(item.getCourseId());
            tk.setTkName(item.getCourseSubject());
            List<TJuanTkVO> tkVOList = new ArrayList<>();
            //当前题库所有题目
            List<TJuanQuestion> itemList = questionMap.get(item.getCourseId());
            if (null == itemList) {
                continue;
            }
            //题目类型
            TJuanTkVO type = new TJuanTkVO();
            List<TJuanTkChildVO> typelist = new ArrayList<>();
            type.setName("题目类型");
            type.setDictType("topic_type");
            Map<String, List<TJuanQuestion>> typeMap = itemList.stream().collect(Collectors.groupingBy(TJuanQuestion::getQuestionType));
            for (SysDictData item1 : topicType) {
                TJuanTkChildVO childVO1 = new TJuanTkChildVO();
                typeMap.get(item1.getDictValue());
                if (null == typeMap.get(item1.getDictValue())) {
                    childVO1.setCount(0);
                } else {
                    childVO1.setCount(typeMap.get(item1.getDictValue()).size());
                }
                childVO1.setName(item1.getDictLabel());
                childVO1.setDictName(item1.getDictValue());
                typelist.add(childVO1);
            }
            type.setList(typelist);
            tkVOList.add(type);
            //难易程度
            TJuanTkVO difficul = new TJuanTkVO();
            List<TJuanTkChildVO> difficullist = new ArrayList<>();
            difficul.setName("难易程度");
            difficul.setDictType("difficulty");
            Map<String, List<TJuanQuestion>> difficulMap = itemList.stream().collect(Collectors.groupingBy(TJuanQuestion::getQuestionEasy));
            for (SysDictData item2 : difficulty) {
                TJuanTkChildVO childVO2 = new TJuanTkChildVO();
                difficulMap.get(item2.getDictValue());
                if (null == difficulMap.get(item2.getDictValue())) {
                    childVO2.setCount(0);
                } else {
                    childVO2.setCount(difficulMap.get(item2.getDictValue()).size());
                }
                childVO2.setName(item2.getDictLabel());
                childVO2.setDictName(item2.getDictValue());
                difficullist.add(childVO2);
            }
            difficul.setList(difficullist);
            tkVOList.add(difficul);
            //重要性
            TJuanTkVO gd = new TJuanTkVO();
            List<TJuanTkChildVO> gdlist = new ArrayList<>();
            gd.setName("重要性");
            gd.setDictType("grade");
            Map<String, List<TJuanQuestion>> gdMap = itemList.stream().collect(Collectors.groupingBy(TJuanQuestion::getQuestionGrade));
            for (SysDictData item3 : grade) {
                TJuanTkChildVO childVO3 = new TJuanTkChildVO();
                gdMap.get(item3.getDictValue());
                if (null == gdMap.get(item3.getDictValue())) {
                    childVO3.setCount(0);
                } else {
                    childVO3.setCount(gdMap.get(item3.getDictValue()).size());
                }
                childVO3.setName(item3.getDictLabel());
                childVO3.setDictName(item3.getDictValue());
                gdlist.add(childVO3);
            }
            gd.setList(gdlist);
            tkVOList.add(gd);
            //能力层次
            TJuanTkVO capability = new TJuanTkVO();
            List<TJuanTkChildVO> capabilitylist = new ArrayList<>();
            capability.setName("能力层次");
            capability.setDictType("capability_level");
            Map<String, List<TJuanQuestion>> capabilityMap = itemList.stream().collect(Collectors.groupingBy(TJuanQuestion::getCapabilityLevel));
            for (SysDictData item4 : capabilityLevel) {
                TJuanTkChildVO childVO4 = new TJuanTkChildVO();
                capabilityMap.get(item4.getDictValue());
                if (null == capabilityMap.get(item4.getDictValue())) {
                    childVO4.setCount(0);
                } else {
                    childVO4.setCount(capabilityMap.get(item4.getDictValue()).size());
                }
                childVO4.setName(item4.getDictLabel());
                childVO4.setDictName(item4.getDictValue());
                capabilitylist.add(childVO4);
            }
            capability.setList(capabilitylist);
            tkVOList.add(capability);

            //数据组装
            tk.setTJuanTkVOList(tkVOList);
            result.add(tk);
        }

        return result;
    }

    /**
     * 题库-汇总统计
     * @return
     */
    @Override
    public List<TJuanTkTotal> getStatisticsByTotal(TJuanCourseDto dto) {
        List<TJuanCourseVo> list = baseMapper.getStatisticsByTotal(dto);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        //查询当前所属题库下所有题目
        List<String> tkIds = list.stream().map(TJuanCourseVo::getCourseId).collect(Collectors.toList());
        List<TJuanQuestion> qsList = questionMapper.selectAllQuestionByUser(tkIds);
        Map<String, List<TJuanQuestion>> questionMap = qsList.stream().collect(Collectors.groupingBy(TJuanQuestion::getCourseId));
        //题目类型字典
        List<SysDictData> topicType = CacheUtils.get(CacheNames.SYS_DICT, "topic_type");
        //难易程度字典
        List<SysDictData> difficulty = CacheUtils.get(CacheNames.SYS_DICT, "difficulty");
        //重要性字典
        List<SysDictData> grade = CacheUtils.get(CacheNames.SYS_DICT, "grade");
        //能力层次字典
        List<SysDictData> capabilityLevel = CacheUtils.get(CacheNames.SYS_DICT, "capability_level");
        // 最终返回结果
        List<TJuanTkTotal> result = new ArrayList<>();
        for (TJuanCourseVo item : list) {
            TJuanTkTotal tk = new TJuanTkTotal();
            tk.setTkId(item.getCourseId());
            tk.setTkName(item.getCourseSubject());
            List<TJuanTkVO> tkVOList = new ArrayList<>();
            //当前题库所有题目
            List<TJuanQuestion> itemList = questionMap.get(item.getCourseId());
            if (null == itemList) {
                continue;
            }
            //题目类型
            TJuanTkVO type = new TJuanTkVO();
            List<TJuanTkChildVO> typelist = new ArrayList<>();
            type.setName("题目类型");
            type.setDictType("topic_type");
            Map<String, List<TJuanQuestion>> typeMap = itemList.stream().collect(Collectors.groupingBy(TJuanQuestion::getQuestionType));
            for (SysDictData item1 : topicType) {
                TJuanTkChildVO childVO1 = new TJuanTkChildVO();
                typeMap.get(item1.getDictValue());
                if (null == typeMap.get(item1.getDictValue())) {
                    childVO1.setCount(0);
                } else {
                    childVO1.setCount(typeMap.get(item1.getDictValue()).size());
                }
                childVO1.setName(item1.getDictLabel());
                childVO1.setDictName(item1.getDictValue());
                typelist.add(childVO1);
            }
            type.setList(typelist);
            tkVOList.add(type);
            //难易程度
            TJuanTkVO difficul = new TJuanTkVO();
            List<TJuanTkChildVO> difficullist = new ArrayList<>();
            difficul.setName("难易程度");
            difficul.setDictType("difficulty");
            Map<String, List<TJuanQuestion>> difficulMap = itemList.stream().collect(Collectors.groupingBy(TJuanQuestion::getQuestionEasy));
            for (SysDictData item2 : difficulty) {
                TJuanTkChildVO childVO2 = new TJuanTkChildVO();
                difficulMap.get(item2.getDictValue());
                if (null == difficulMap.get(item2.getDictValue())) {
                    childVO2.setCount(0);
                } else {
                    childVO2.setCount(difficulMap.get(item2.getDictValue()).size());
                }
                childVO2.setName(item2.getDictLabel());
                childVO2.setDictName(item2.getDictValue());
                difficullist.add(childVO2);
            }
            difficul.setList(difficullist);
            tkVOList.add(difficul);
            //重要性
            TJuanTkVO gd = new TJuanTkVO();
            List<TJuanTkChildVO> gdlist = new ArrayList<>();
            gd.setName("重要性");
            gd.setDictType("grade");
            Map<String, List<TJuanQuestion>> gdMap = itemList.stream().collect(Collectors.groupingBy(TJuanQuestion::getQuestionGrade));
            for (SysDictData item3 : grade) {
                TJuanTkChildVO childVO3 = new TJuanTkChildVO();
                gdMap.get(item3.getDictValue());
                if (null == gdMap.get(item3.getDictValue())) {
                    childVO3.setCount(0);
                } else {
                    childVO3.setCount(gdMap.get(item3.getDictValue()).size());
                }
                childVO3.setName(item3.getDictLabel());
                childVO3.setDictName(item3.getDictValue());
                gdlist.add(childVO3);
            }
            gd.setList(gdlist);
            tkVOList.add(gd);
            //能力层次
            TJuanTkVO capability = new TJuanTkVO();
            List<TJuanTkChildVO> capabilitylist = new ArrayList<>();
            capability.setName("能力层次");
            capability.setDictType("capability_level");
            Map<String, List<TJuanQuestion>> capabilityMap = itemList.stream().collect(Collectors.groupingBy(TJuanQuestion::getCapabilityLevel));
            for (SysDictData item4 : capabilityLevel) {
                TJuanTkChildVO childVO4 = new TJuanTkChildVO();
                capabilityMap.get(item4.getDictValue());
                if (null == capabilityMap.get(item4.getDictValue())) {
                    childVO4.setCount(0);
                } else {
                    childVO4.setCount(capabilityMap.get(item4.getDictValue()).size());
                }
                childVO4.setName(item4.getDictLabel());
                childVO4.setDictName(item4.getDictValue());
                capabilitylist.add(childVO4);
            }
            capability.setList(capabilitylist);
            tkVOList.add(capability);

            //数据组装
            tk.setTJuanTkVOList(tkVOList);
            result.add(tk);
        }
        return result;
    }
    @Override
    public R mergeCourse(String mainId, List<String> ids) {
        if (StringUtils.isNotBlank(mainId) && CollectionUtils.isNotEmpty(ids)) {
            //记录所有从库的章节
            List<String> allChapter = new ArrayList<>();
            List<TJuanChapterOutVo> chapterEntity = new ArrayList<>();
            //先查询出所有从库的数据
            for (String id : ids) {
                //查询从库的章节
                LambdaQueryWrapper<TJuanChapter> lqw = new LambdaQueryWrapper<>();
                lqw.eq(TJuanChapter::getCourseId, id).orderByAsc(TJuanChapter::getChapterSort);
                List<TJuanChapter> chapters = tJuanChapterMapper.selectList(lqw);
                if (CollectionUtils.isNotEmpty(chapters)) {
                    List<TJuanChapterOutVo> outVos = new ArrayList<>();
                    for (TJuanChapter juanChapter : chapters) {
                        //将从库中的章节迁移至主库
                        juanChapter.setCourseId(mainId);
                        //将code置空
                        juanChapter.setChapterCode(null);
                        TJuanChapterOutVo outVo = new TJuanChapterOutVo();
                        BeanUtils.copyProperties(juanChapter, outVo);
                        outVos.add(outVo);
                        allChapter.add(outVo.getChapterId());
                    }
                    itJuanChapterService.saveBatch(outVos, mainId);
                    chapterEntity.addAll(outVos);
                }
            }
            //查出所有从库的知识点
            LambdaQueryWrapper<TJuanKnowledge> lqw = new LambdaQueryWrapper<>();
            lqw.in(TJuanKnowledge::getChapterId, allChapter);
            List<TJuanKnowledge> knowledges = juanKnowledgeMapper.selectList(lqw);
            if (CollectionUtils.isNotEmpty(knowledges)) {
                //先给章节按id分个组，这样可以不用去数据库查询章节
                Map<String, List<TJuanChapterOutVo>> listMap = chapterEntity.stream().collect(Collectors.groupingBy(TJuanChapterOutVo::getChapterId));
                //循环知识点，更新每个知识点的编号
                for (TJuanKnowledge tJuanKnowledge : knowledges) {
                    //更新知识点的编号，先查出章节更新后的编号
                    String code = listMap.get(tJuanKnowledge.getChapterId()).get(0).getChapterCode();
                    tJuanKnowledge.setKnowledgeCode(code + tJuanKnowledge.getKnowledgeCode().substring(2));
                }
                //全局更新知识点
                juanKnowledgeMapper.updateBatchById(knowledges);
            }
            return R.ok("题库合并成功!");
        }
        return R.fail("请勾选两个以上的题库进行合并");
    }
}
